package com.data;

import com.gooddies.utils.IteratorToIterable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author sad
 */
public class UniverseManager {

    private static final UniverseManager instance = new UniverseManager();
    private final List<Universe> universes = new ArrayList<>();

    public static UniverseManager getInstance() {
        return instance;
    }

    private UniverseManager() {
        for (int i = 0; i < 18; i++) {
            addDefaultUniverse(i);
        }
    }

    private void addDefaultUniverse(int position) {
        Universe universe = new Universe();
        universe.setPosition(position);
        universe.setIndex(position % 6);
        universe.setIp("127.0.0.1");
        universe.setSubNet(0);
        universe.setPort(6439 + position / 6);
        addUniverse(universe);
    }

    private void addUniverse(Universe universe) {
        universes.add(universe);
    }

    public int universesCount() {
        return universes.size();
    }

    public Universe getUniverse(int position) {
        return universes.get(position);
    }

    public Iterable<Universe> iterator() {
        return IteratorToIterable.once(universes.iterator());
    }

    private final int[][] wheelmask = new int[][]{
        {1, 1, -1, -1, -1, 1, 1},
        {1, -1, -1, -1, -1, -1, 1},
        {-1, -1, -1, -1, -1, -1, -1},
        {-1, -1, -1, -1, -1, -1, -1},
        {-1, -1, -1, -1, -1, -1, -1},
        {1, -1, -1, -1, -1, -1, 1},
        {1, 1, -1, -1, -1, 1, 1},};

    public void createPixelMapping(int[] pixelMapping) {
        int index = 0;
        for (int j = 12; j >= 0; j--) {
            for (int i = 0; i < 13; i++, index++) {
                int y = j;
                if (j % 2 == 1) {
                    int x = 13 - i - 1;
                    pixelMapping[index] = y * 13 + x;
                } else {
                    int x = i;
                    pixelMapping[index] = y * 13 + x;
                }
            }
        }
    }

    public void recalculateMasks() {
        for (int i = 0; i < universesCount(); i++) {
            Universe universe = getUniverse(i);
            createPixelMapping(universe.getPixelMapping());
            int y = i / 6;
            int x = i - y * 6;
            y *= 13;
            x *= 13;
            for (Wheel w : WheelManager.getInstace().getWheels()) {
                int wX = w.getScreenX();
                int wY = w.getScreenY();
                wX -= 3;
                wY -= 3;
                copyWheelShadowToMask(wX, wY, universe.getPixelMapping(), x, y);

            }
            //printMapping(universe.getPixelMapping());
            // collapseShadowMask(universe.getPixelMapping());
            int wheelOffset = 0;
            for (int value : universe.getPixelMapping()) {
                if (value != -1) {
                    wheelOffset++;
                }
            }

            universe.setWheelIndexOffset(wheelOffset * 3);
        }
    }

 /*   private void printMapping(int[] mapping) {
        int sample = 0;
        for (int j = 12; j >= 0; j--) {
            for (int i = 0; i < 13; i++, sample++) {
                System.out.print(String.format("%3d ", mapping[j * 13 + i]));
            }
            System.out.println();
        }
        System.out.println();
    }
*/
    public int[] collapseShadowMask(int[] mask) {
        int[] newMask = mask;
        //Arrays.fill(newMask, -1);
        int index = 0;
        int skipped = 0;
        for (int i = 0; i < mask.length; i++) {
            if (!(mask[i] == -1)) {
                newMask[index] = mask[i];
                index++;
            } else {
                skipped++;
            }
        }
        for (; index < newMask.length; index++) {
            newMask[index] = -1;
        }

        return newMask;
    }

    private void copyWheelShadowToMask(int wheelX, int wheelY, int[] mask, int universeX, int universeY) {
        int universeX2 = universeX + 13;
        int universeY2 = universeY + 13;
        for (int j = 0; j < 7; j++) {
            for (int i = 0; i < 7; i++) {
                int tx = wheelX + i;
                int ty = wheelY + j;
                if (tx >= universeX && tx < universeX2 && ty >= universeY && ty < universeY2) {
                    tx -= universeX;
                    ty -= universeY;
                    if (wheelmask[i][j] == -1) {
                        ty = (12 - ty);//поставил сюда иначе не работает Artnet copyPictureDataToUniverse
                        if (ty % 2 == 1) {
                            mask[ ty * 13 + (12 - tx)] = -1;
                        } else {
                            mask[ ty * 13 + tx] = -1;
                        }
                    }
                }
            }
        }
    }
}
